﻿using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB;

namespace StairsModuleAndEdit.StairsModel.AddSigns
{
	internal class LevelFinder
	{
		private LevelFinder(Document m_doc)
		{
			this.m_doc = m_doc;
			this.makeListLeveles();
		}

		internal static LevelFinder GetLevelFinder(Document m_doc)
		{
			if (LevelFinder.singleTag == null || m_doc == null || LevelFinder.singleTag.m_doc != m_doc)
			{
				LevelFinder.singleTag = new LevelFinder(m_doc);
			}
			return LevelFinder.singleTag;
		}

		private void makeListLeveles()
		{
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.m_doc);
			ElementCategoryFilter elementCategoryFilter = new ElementCategoryFilter(StaticRescours.LevelCategory);
			foreach (Element element in filteredElementCollector.WherePasses(elementCategoryFilter).ToElements())
			{
				if (element is Level)
				{
					this.listLeveles.Add(element as Level);
				}
			}
			this.listLeveles = (from k in this.listLeveles
			orderby k.Elevation
			select k).ToList<Level>();
		}

		internal Level GetTopLevel(double elevation)
		{
			Level result = null;
			int num = -1;
			double num2 = double.MaxValue;
			for (int i = 0; i < this.listLeveles.Count; i++)
			{
				if (this.listLeveles[i].Elevation > elevation && this.listLeveles[i].Elevation - elevation < num2)
				{
					num2 = this.listLeveles[i].Elevation - elevation;
					num = i;
				}
			}
			if (num >= 0)
			{
				result = this.listLeveles[num];
			}
			return result;
		}

		internal Level GetTopLevel(PackerBase input)
		{
			Level result = null;
			int num = -1;
			double num2 = double.MaxValue;
			double z;
			if (input.UseTransform == null)
			{
				z = input.ThisFamilyInstanceLocation.Point.Z;
			}
			else
			{
				XYZ xyz = Utility.TransformPoint(input.ThisFamilyInstanceLocation.Point, input.UseTransform);
				z = xyz.Z;
			}
			for (int i = 0; i < this.listLeveles.Count; i++)
			{
				if (this.listLeveles[i].Elevation > z && num2 > this.listLeveles[i].Elevation - z)
				{
					num = i;
					num2 = this.listLeveles[i].Elevation - z;
				}
			}
			if (-1 != num)
			{
				result = this.listLeveles[num];
			}
			return result;
		}

		private Document m_doc;

		private List<Level> listLeveles = new List<Level>();

		private static LevelFinder singleTag;
	}
}
